/*--------------------------------------------------------------------------------------*\
**
** army_info_window.cpp
**
** Heroes IV
** Copyright 2000, The 3DO Company
**
\*--------------------------------------------------------------------------------------*/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "army_info_window.h"

#include "abbreviate_number.h"
#include "adventure_frame.h"
#include "adventure_map.h"
#include "army.h"
#include "army_array.h"
#include "army_dialog.h"
#include "army_dialog_garrison.h"
#include "basic_dialog.h"
#include "bitmap_group.h"
#include "bitmap_group_cache.h"
#include "bitmap_layer_window.h"
#include "bound_handler.h"
#include "button.h"
#include "button_cache.h"
#include "combat_result.h"
#include "creature.h"
#include "creature_array.h"
#include "creature_array_window.h"
#include "creature_info_window.h"
#include "creature_stack.h"
#include "creature_traits.h"
#include "dialog_garrison.h"
#include "estimate_outcome.h"
#include "external_string.h"
#include "format_string.h"
#include "game_window.h"
#include "get_artifact_damage_modifier.h"
#include "hero.h"
#include "item_help_block.h"
#include "interface_help.h"
#include "luck_icon_window.h"
#include "morale_icon_window.h"
#include "ownable_garrisonable_adv_object.h"
#include "player.h"
#include "player_color.h"
#include "popup_window.h"
#include "replace_keywords.h"
#include "skill.h"
#include "skill_icon.h"
#include "spell.h"
#include "standard_fonts.h"
#include "town.h"
#include "town_properties.h"
#include "town_type.h"

extern  t_bitmap_group_cache g_army_layout;
extern  t_button_cache g_ok_button;
extern  t_external_string const	k_text_class_level;
extern  t_external_string const k_text_shots( "shots.dialog" );
extern  t_external_string const k_text_not_applicable;
extern  t_external_string const k_text_infinity_abbreviation;

t_bitmap_group_cache k_army_info_bitmaps ("dialog.army_right_click");

t_button* create_blacksmith_button( std::string const& name, t_bitmap_group_ptr bitmap_ptr, t_window *parent_window );



/*------------------------------------------------------------------------------------------------*\
** Army info window constructor.  Army info shows info for an army based on the scouting
**  skill level parameter.
\*------------------------------------------------------------------------------------------------*/
t_army_info_window::t_army_info_window ( t_creature_array* creature_ptr, t_skill_mastery skill_level, t_window* parent )
					: t_window( k_completely_transparent, parent )
{
	t_screen_rect       rect;

	m_bitmaps_ptr = k_army_info_bitmaps.get();
	m_army = creature_ptr;
    // For skill icons...
    m_army_layout = g_army_layout.get();
    m_scouting_skill_level = skill_level;
	m_is_boat = creature_ptr->is_boat();

	/*
    ** Create background.
    */
	t_bitmap_layer const*   layer;
	//t_bitmap_layer const*   frame_layer;
	t_screen_point          origin(0,0);
	t_screen_point          point(0,0);
    
	layer = m_bitmaps_ptr->find( "background" );
	m_background = new t_bitmap_layer_window( layer, origin, this );

    // Icons.
    create_icons();
    create_text_windows();
	create_buttons();

    /*
    ** Army portraits. Also shows quantity.
    ** Basic scouting gives player knowledge of exact number in creature stack.
    */
	rect = m_bitmaps_ptr->find("creature_circles")->get_rect();
	point = rect.top_left();
   	m_creature_window_ptr = new t_creature_info_window( point, creature_ptr, 
														m_scouting_skill_level,
														t_creature_info_window::k_single_row, 
														m_background );
   	m_creature_window_ptr->set_select_handler( bound_handler( *this, &t_army_info_window::army_select ) );

    // Select default creature.
    m_selected_slot = -1;
    m_creature_window_ptr->select_first();


    /*
    ** Init this window.
    */
	t_screen_rect parent_rect;

	parent_rect = get_parent()->get_client_rect();
	rect = m_bitmaps_ptr->get_rect();
	rect += (parent_rect.size() - rect.size()) / 2;
	init( rect );
}

// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------
void t_army_info_window::create_icons()
{
	t_bitmap_layer const*   layer;
	t_window *              window;
    t_screen_rect           rect;
	t_screen_point          origin(0,0);
	//t_screen_point          point(0,0);
	t_help_block const&     shared_help = get_help_block( "shared" );
	t_help_block const&     help = get_help_block( "army_screen" );

	layer = m_bitmaps_ptr->find( "damage" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, shared_help, "damage" );

	layer = m_bitmaps_ptr->find( "melee_attack" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, help, "melee_attack" );

	layer = m_bitmaps_ptr->find( "melee_defense" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, help, "melee_defense" );

	layer = m_bitmaps_ptr->find( "hit_points" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, shared_help, "hit_points" );
    
    // Morale
	rect = m_bitmaps_ptr->find( "morale" )->get_rect();
	m_morale_icon = new t_morale_icon_window( rect, m_background );

	layer = m_bitmaps_ptr->find( "speed" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, shared_help, "speed" );
    
	layer = m_bitmaps_ptr->find( "movement" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, shared_help, "adventure_movement" );
	
    layer = m_bitmaps_ptr->find( "ranged_attack" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, help, "ranged_attack" );
    
    layer = m_bitmaps_ptr->find( "ranged_defense" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, help, "ranged_defense" );
    
    layer = m_bitmaps_ptr->find( "shots" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, shared_help, "shots" );
    
    layer = m_bitmaps_ptr->find( "spell_points" );
	window = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( window, shared_help, "spell_points" );
	
    rect = m_bitmaps_ptr->find( "luck" )->get_rect();
	m_luck_icon = new t_luck_icon_window( rect, m_background );
    
    layer = m_bitmaps_ptr->find( "experience" );
	m_experience_icon = new t_bitmap_layer_window( layer, origin, m_background );
	set_help( m_experience_icon, shared_help, "experience" );
   
	t_screen_point      point(0,0);
    // Skill icons.
    for (int i=0; i<k_max_skills_to_display; i++)
    {
        rect = t_screen_rect(0, 0, 52, 52);
	    point = m_bitmaps_ptr->find(format_string( "skill_%i", i+1))->get_rect().top_left();
        rect += point;
        rect += origin;
		m_skill_icons[i] = new t_skill_icon( rect, m_background );
    }

	layer = m_bitmaps_ptr->find( "skills_frame" );
	window = new t_bitmap_layer_window( layer, origin, m_background );

}

// ---------------------------------------------------------------------------------
// create buttons
// ---------------------------------------------------------------------------------
void t_army_info_window::create_buttons()
{
	t_help_block const&     shared_help = get_help_block( "shared" );
	t_help_block const&     help = get_help_block( "army_info" );
	t_button*               button;
	t_screen_rect			rect;
	t_button_handler		handler;

	rect = m_bitmaps_ptr->find( "close_button" )->get_rect();
	button = new t_button( g_ok_button.get(), rect.top_left(), m_background );
	handler = bound_handler(*this, &t_army_info_window::close_click );
	button->set_click_handler( handler );
	set_help( button, shared_help, "ok" );

	// create open-army button
	if (m_scouting_skill_level < k_mastery_grand_master)
		return;

	if ( m_army->get_town() )
	{
		button = create_button( m_bitmaps_ptr, "town", m_background, t_screen_point(0,0) );
		handler = bound_handler( *this, &t_army_info_window::open_town_click );
		button->set_click_handler( handler );
		set_help( button, help, "open_town" );
	}
	else if ( m_army->get_ownable_garrison() )
	{
		button = create_button( m_bitmaps_ptr, "town", m_background, t_screen_point(0,0) );
		handler = bound_handler( *this, &t_army_info_window::open_garrison_click );
		button->set_click_handler( handler );
		set_help( button, help, "open_garrison" );
	}
	else if ( m_army->get_army() )
	{
		button = create_button( m_bitmaps_ptr, "army", m_background, t_screen_point(0,0) );
		handler = bound_handler( *this, &t_army_info_window::open_army_click );
		button->set_click_handler( handler );
		set_help( button, help, "open_army" );
	}
}

static t_external_string const k_neutral_army_title( "right_click_title.neutral_army");
static t_external_string const k_your_army_title( "right_click_title.your_army");
static t_external_string const k_other_army_title( "right_click_title.other_army");

// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------
void t_army_info_window::create_text_windows()
{
    t_screen_rect   rect;
	t_pixel_24      color(0,0,0);
	t_pixel_24      drop_shadow_color(200,200,200);
	t_text_window * text_window;

	std::string title;

	t_army * army = m_army->get_army();

	if ( army )
	{
		int owner = army->get_owner_number();
		t_adventure_map * map = army->get_map();

		assert( map );

		if ( owner < 0 || map == NULL )
		{
			title = k_neutral_army_title;
		}
		else if ( owner == map->get_player_number() )
		{
			title = k_your_army_title;
		}
		else
		{
			title = replace_keywords( k_other_army_title, 
									  "%color", get_player_color_name( map->get_player( owner ).get_color() ) );
		}
	}
	else
	{
		t_adventure_object * object = m_army->get_adventure_object();

		assert( object );

		if ( object )
		{
			title = object->get_name();
		}
	}

	rect = m_bitmaps_ptr->find( "title" )->get_rect();
	text_window = new t_text_window( get_font( rect.height() ), rect, m_background, title, color );
	text_window->set_drop_shadow( true, drop_shadow_color );
	text_window->set_justification( k_justify_center );

	rect = m_bitmaps_ptr->find( "level" )->get_rect();
	m_level_window = new t_text_window( get_font( rect.height() ), rect, m_background, "",
		                                color );
	m_level_window->set_drop_shadow( true, drop_shadow_color );

	rect = m_bitmaps_ptr->find( "alignment" )->get_rect();
	m_alignment_window = new t_text_window( get_font( rect.height() ), rect, m_background, "",
		                                color );
	m_alignment_window->set_drop_shadow( true, drop_shadow_color );

	std::string stealth_text;

	if (m_scouting_skill_level >= k_mastery_expert)
		stealth_text = get_outcome_text( *m_army );
	rect = m_bitmaps_ptr->find( "stealth" )->get_rect();
	m_stealth_window = new t_text_window( get_font( rect.height() ), rect, m_background, 
										  stealth_text, color );
	m_stealth_window->set_drop_shadow( true, drop_shadow_color );

	rect = m_bitmaps_ptr->find( "damage_text" )->get_rect();
	m_damage_text = new t_text_window( get_font( 14 ), //rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_damage_text->set_center_horizontal();

	rect = m_bitmaps_ptr->find( "melee_attack_text" )->get_rect();
	m_melee_offense_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_melee_offense_text->set_center_horizontal();
   
	rect = m_bitmaps_ptr->find( "melee_defense_text" )->get_rect();
	m_melee_defense_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_melee_defense_text->set_center_horizontal();
   
	rect = m_bitmaps_ptr->find( "hit_points_text" )->get_rect();
	m_hitpoints_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_hitpoints_text->set_center_horizontal();
   
	rect = m_bitmaps_ptr->find( "morale_text" )->get_rect();
	m_morale_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_morale_text->set_center_horizontal();
   
	rect = m_bitmaps_ptr->find( "luck_text" )->get_rect();
	m_luck_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_luck_text->set_center_horizontal();
   
	rect = m_bitmaps_ptr->find( "speed_text" )->get_rect();
	m_speed_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_speed_text->set_center_horizontal();
    
	rect = m_bitmaps_ptr->find( "movement_text" )->get_rect();
	m_movement_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_movement_text->set_center_horizontal();
   
	rect = m_bitmaps_ptr->find( "ranged_attack_text" )->get_rect();
	m_ranged_offense_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_ranged_offense_text->set_center_horizontal();
    
	rect = m_bitmaps_ptr->find( "ranged_defense_text" )->get_rect();
	m_ranged_defense_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_ranged_defense_text->set_center_horizontal();
    
	rect = m_bitmaps_ptr->find( "shots_text" )->get_rect();
	m_shots_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_shots_text->set_center_horizontal();
    
	rect = m_bitmaps_ptr->find( "spell_points_text" )->get_rect();
	m_spell_points_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_spell_points_text->set_center_horizontal();
    
	rect = m_bitmaps_ptr->find( "experience_text" )->get_rect();
	m_experience_text = new t_text_window( get_font( rect.height() ), 
                    rect, m_background, "", t_pixel_24( 0,0,0 ) );
	m_experience_text->set_center_horizontal();
}

void t_army_info_window::close_click( t_button* button )
{
	close();
}

void t_army_info_window::army_select( t_creature_info_window* window_ptr, int slot_index )
{
    if (m_selected_slot == slot_index)
        return;

    m_selected_slot = slot_index; //  m_creature_window_ptr->get_selected_slot();

    if (slot_index == -1)
        return;

    t_creature_stack const * creature_stack_ptr = m_creature_window_ptr->get_selected_army();
	t_creature_array const &army = *(m_creature_window_ptr->get_army());
	t_hero const*   hero;

	std::string		  text;

	hero = creature_stack_ptr->get_hero();
    // Level.
	if (hero != 0)
    {
		text = hero->get_class_name();
		text = replace_keywords( k_text_class_level, "%level", 
			                      format_string( "%i", hero->get_level() )) + " " + text;
    }
	else
	{
		if ( m_scouting_skill_level < k_mastery_advanced )
		{
			text = creature_stack_ptr->get_name( false, 2 ); // Always use plural version of name to avoid
															 // giving away that there is only 1 of a creature
		}
		else
		{
			text = creature_stack_ptr->get_name(); 
		}

		text = capitalize_words( text );
	}

	m_level_window->set_text( text );

	m_alignment_window->set_text( capitalize_words( get_alignment_name( creature_stack_ptr->get_alignment() ) ) );

    show_stats();
    show_skills();
}

/*
** Clicked on skill icon.
*/
void t_army_info_window::show_skills()
{
    int i;
   
	// Reset skill icons.
    for (i=0; i< k_max_skills_to_display; i++)
    {
        t_skill null_skill = t_skill (k_skill_none, k_mastery_none);
            
        m_skill_icons[i]->set_skill ( null_skill );
        m_skill_icons[i]->set_ability (k_ability_none);
    }

    t_creature_stack const * creature_stack_ptr = m_creature_window_ptr->get_selected_army();
	//t_creature_array const &army = *(m_creature_window_ptr->get_army());

	if ( creature_stack_ptr == NULL )
		return;
   
	t_hero const *hero_ptr = creature_stack_ptr->get_const_hero();

    // If hero, show skills.
    if (hero_ptr)
    {
		/*
		** Only see skills with master scouting
		*/
		if (m_scouting_skill_level < k_mastery_master)
			return;

		std::vector<t_skill> skills = hero_ptr->get_skills();

        int num_skills_to_display = skills.size();

        if (num_skills_to_display > k_max_skills_to_display)
            num_skills_to_display = k_max_skills_to_display;

        for (i=0; i< num_skills_to_display; i++)
        {
            m_skill_icons[i]->set_skill ( skills[i] );
        }
    }
    // Else show creature traits.
    else
    {
	    t_creature const * creature = creature_stack_ptr->get_creature();

		if ( creature )
		{
			t_creature_traits const& creature_traits = creature->get_traits();
			std::vector<t_creature_ability> abilities = creature_traits.abilities;

			for (i=0; i< abilities.size(); i++)
			{
				m_skill_icons[i]->set_ability ( abilities[i] );
			}
		}        
    }
}

// ---------------------------------------------------------------
// open an army dialog 
// ---------------------------------------------------------------
void t_army_info_window::open_army_click( t_button* )
{
	t_adventure_frame*	adventure_frame = m_army->get_adventure_frame();
	t_army *            army = m_army->get_army();

	assert( army );

	close();
	adventure_frame->run_army_dialog( army );
}

// ---------------------------------------------------------------
// open a town dialog 
// ---------------------------------------------------------------
void t_army_info_window::open_town_click( t_button* )
{
	t_adventure_frame*	adventure_frame = m_army->get_adventure_frame();
	t_town*				town = m_army->get_town();

	assert( town );

	close();

	if ( town )
	{
		adventure_frame->do_town_dialog( town, 0 );
	}
}

// ---------------------------------------------------------------
// open a garrison dialog 
// ---------------------------------------------------------------
void t_army_info_window::open_garrison_click( t_button* )
{
	t_adventure_frame*	adventure_frame = m_army->get_adventure_frame();
	t_adventure_map *   adventure_map = adventure_frame->get_map();
	t_ownable_garrisonable_adv_object * garrison = m_army->get_ownable_garrison();

	assert( garrison );

	close();

	if ( garrison )
	{
		if ( garrison->get_owner_number() == adventure_map->get_player_number() )
		{
			garrison->run_garrison_dialog( NULL );
		}
		else
		{
			// Garrison dialog is useless to other players; just go to the army dialog for
			// the garrison
			t_window_ptr dialog = new t_army_dialog_garrison( garrison, NULL, adventure_frame );
			dialog->run_modal();
		}
	}
}

void t_army_info_window::show_stats()
{
    t_creature_stack const * creature_stack_ptr = m_creature_window_ptr->get_selected_army();
	t_creature_array const &army = *(m_creature_window_ptr->get_army());
	std::string text;

    /*
    ** If nothing selected, return
    */
	if ( creature_stack_ptr == NULL )
		return;

    /*
    ** If scouting level is Master, show stats.
    */
    if (m_scouting_skill_level < k_mastery_master)
        return;

    // Hitpoints
	if (creature_stack_ptr->get_wounds() > 0)
		text = format_string( "%i\n(%i)", creature_stack_ptr->get_hit_points() - creature_stack_ptr->get_wounds(),
		                      creature_stack_ptr->get_hit_points() );
	else
		text = format_string( "%i", creature_stack_ptr->get_hit_points() );
    m_hitpoints_text->set_text ( text );

    // Damage
	float melee_offense = creature_stack_ptr->get_offense( false, army );
	float ranged_offense = creature_stack_ptr->get_offense( true, army );

	bool    ranged = creature_stack_ptr->has_ability( k_ability_ranged );
	int     artifact_damage = get_artifact_damage( *creature_stack_ptr, ranged );
	int     damage_low = creature_stack_ptr->get_damage_low() + artifact_damage;
	int     damage_high = creature_stack_ptr->get_damage_high() + artifact_damage;
	int     fire_bonus = 0;

	if ( damage_low < 1 )
		damage_low = 1;

	if ( damage_high < 1 )
		damage_high = 1;

	m_damage_text->set_text( format_string( "%i-%i", damage_low, damage_high ) );

	//if (creature_stack_ptr->is_active( k_spell_firebreathing ))
	//{
	//	fire_bonus = creature_stack_ptr->get_effect_power( k_spell_firebreathing );
	//}
	//if (melee_offense != 1.0f)
	text = format_string( "%i", int( melee_offense * 10.0f + 0.5f ) );
	//if (fire_bonus != 0)
	//	text += format_string( " (%+i)", fire_bonus );
	m_melee_offense_text->set_text( text );

    float melee_defense = creature_stack_ptr->get_defense( false, army );
	float ranged_defense = creature_stack_ptr->get_defense( true, army );
	
    text = format_string( "%i", int( melee_defense * 10.0f + 0.5f ) );
	m_melee_defense_text->set_text( text );
	
    text = format_string( "%i", int( ranged_defense * 10.0f + 0.5f ));
	m_ranged_defense_text->set_text( text );

    // Ranged ability?  Else show 'n/a'
	if (creature_stack_ptr->has_ability( k_ability_ranged ))
	{
		std::string shots_text;

        // Shots
	    if (creature_stack_ptr->has_ability( k_ability_unlimited_shots ))
        {
		    shots_text = k_text_infinity_abbreviation;
        }
        else //if (!creature_stack_ptr->has_ability( k_ability_unlimited_shots ))
		{
			shots_text = format_string( " %i ", creature_stack_ptr->get_shots() );
			shots_text += k_text_shots;
		}
		text = format_string( "%i", int( ranged_offense * 10.0f + 0.5f ) );
		m_ranged_offense_text->set_text( text );
		m_shots_text->set_text( shots_text );
	}
    else
    {
		m_ranged_offense_text->set_text ( k_text_not_applicable );
		m_shots_text->set_text( k_text_not_applicable );
    }

    // Movement
	int maximum  = army.get_max_movement( *creature_stack_ptr ) / 100;
	int movement = army.get_movement( *creature_stack_ptr ) / 100;

    //m_movement_text->set_text ( format_string("%i", creature_stack_ptr->get_movement_left()) );
	m_movement_text->set_text( format_string( "%i\n(%i)", movement, maximum ) );

    // Speed
    m_speed_text->set_text ( format_string("%i", creature_stack_ptr->get_speed( army )) );

    // Experience
	t_hero const* hero = creature_stack_ptr->get_hero();

	if (hero == 0)
    {
		m_experience_text->set_text( "" );
        m_experience_icon->set_right_click_text( get_element_help("shared", "creature_experience") );
    }
	else
	{
		text = abbreviate_number( hero->get_experience(), *m_experience_text->get_font(), 
								  m_experience_text->get_width());
		m_experience_text->set_text ( text );
        
	    std::string experience_icon_text;
        int exp_needed = hero->get_experience_needed_for_next_level();
        if (exp_needed)
	        experience_icon_text = replace_keywords( get_element_help("shared", "show_experience"),
						"%amount", format_string("%d", exp_needed) );
        else
	        experience_icon_text = get_element_help("shared", "show_experience_full");

        m_experience_icon->set_right_click_text( experience_icon_text );
	}
    
    // Spell points
    m_spell_points_text->set_text ( format_string("%i", creature_stack_ptr->get_spell_points()) );

    // Luck
    int luck = creature_stack_ptr->get_luck( army );
    m_luck_text->set_text ( format_string("%i", luck ) );
    m_luck_icon->set_value( luck );
    
    // Morale
    int morale = creature_stack_ptr->get_morale( army );
    m_morale_text->set_text ( format_string("%i", 
                            morale ) );
	m_morale_icon->set_value( morale );
}

// ---------------------------------------------------------------
// Run the army info window, including figuring out the needed skill 
// level
// ---------------------------------------------------------------
void run_army_info_window( t_creature_array * creature_ptr, t_adventure_frame* frame )
{
	t_adventure_object* object = creature_ptr->get_adventure_object();
	t_skill_mastery		skill_level = object->get_information_level();

    // Show relevant info for this army.
    t_counted_ptr< t_army_info_window > info_window
		= new t_army_info_window ( creature_ptr, skill_level, frame );
    // No longer a popup.
	info_window->run_modal();
}

